package com.gitee.melin.bee.core.jdbc.parser;

import com.gitee.melin.bee.core.jdbc.enums.DataSourceType;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;

/**
 * Parser based on regular expression
 *
 * @author oburgosm
 * @since 0.2.12
 */
public abstract class AbstractMatcherURLParser implements ConnectionURLParser {

    private final Pattern pattern;

    private final DataSourceType dsType;

    public AbstractMatcherURLParser(Pattern pattern, DataSourceType dsType) {
        this.pattern = pattern;
        this.dsType = dsType;
    }

    /**
     * Useful to modify ConnectionInfo before build
     *
     * @param matcher The matcher to apply. Note that the matcher must have a group named host, and
     *     optionally, a group named port and another named instance
     * @return
     */
    protected JdbcURLInfo.Builder initBuilder(Matcher matcher) {
        String host = matcher.group("host");
        String port = null;
        try {
            port = matcher.group("port");
        } catch (IllegalArgumentException e) {
            // The pattern has no instance port
        }
        JdbcURLInfo.Builder builder;
        if (port == null || "".equals(port)) {
            builder = new JdbcURLInfo.Builder(host);
        } else {
            builder = new JdbcURLInfo.Builder(host + ":" + Integer.valueOf(port));
        }
        String instance = null;
        try {
            instance = matcher.group("instance");
        } catch (IllegalArgumentException e) {
            // The pattern has no instance group
        }

        String options = null;
        try {
            options = matcher.group("options");
        } catch (IllegalArgumentException e) {
            // The pattern has no instance group
        }

        if (StringUtils.isBlank(instance)) {
            instance = parseDbName(options);
        }

        return builder.dsType(this.dsType).dbInstance(instance).dbOptions(options);
    }

    protected String parseDbName(String dbOptions) {
        return null;
    }

    @Override
    public JdbcURLInfo parse(String url) {
        Matcher matcher = this.pattern.matcher(url);
        if (matcher.matches()) {
            return this.initBuilder(matcher).build();
        } else {
            throw new IllegalArgumentException("parse url failure: " + url);
        }
    }
}
